home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / wc_Command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  16.1 KB  |  431 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         wc_Command.c
  5. * RCS:          $Header: wc_Command.c,v 1.3 91/03/14 03:14:32 mayer Exp $
  6. * Description:  XM_COMMAND_WIDGET_CLASS
  7. * Author:       Niels Mayer, HPLabs
  8. * Created:      Fri Oct 27 21:57:58 1989
  9. * Modified:     Thu Oct  3 23:56:43 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: wc_Command.c,v 1.3 91/03/14 03:14:32 mayer Exp $";
  42.  
  43. #include <stdio.h>
  44. #include <Xm/Xm.h>
  45. #include <Xm/Command.h>
  46. #include "winterp.h"
  47. #include "user_prefs.h"
  48. #include "xlisp/xlisp.h"
  49. #include "w_funtab.h"
  50. #include "w_XmString.h"
  51.  
  52. extern Widget Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(); /* w_classes.c */
  53.  
  54.  
  55. /*****************************************************************************
  56.  * (send XM_COMMAND_WIDGET_CLASS :new
  57.  *                 [:managed/:unmanaged]
  58.  *                           [<name>]
  59.  *                           <parent> 
  60.  *                           [:XMN_<arg1> <val1>]
  61.  *                           [. . .             ]
  62.  *                           [:XMN_<argN> <valN>])
  63.  *
  64.  * Create a new widget via XmCreateCommand().
  65.  *
  66.  * The optional keyword-argument :managed will cause a subsequent call to
  67.  * XtManageChild(). If the submessage :unmanaged is present, or no submessage,
  68.  * then XtManageChild() won't be called, and the resulting widget will be
  69.  * returned unmanaged.
  70.  ****************************************************************************/
  71. LVAL Xm_Command_Widget_Class_Method_ISNEW()
  72. {
  73.   extern ArgList Wres_Get_LispArglist(); /* from w_resources.c */
  74.   extern void    Wres_Free_C_Arglist_Data(); /* from w_resources.c */
  75.   extern LVAL k_managed, k_unmanaged;
  76.   LVAL self, o_parent;
  77.   char* name;
  78.   Boolean managed_p;
  79.   Widget parent_widget_id, widget_id;
  80.  
  81.   self = xlgaobject();        /* NOTE: xlobj.c:clnew() returns an OBJECT; if this method
  82.                    returns successfully, it will return a WIDGETOBJ */
  83.  
  84.   /* get optional managed/unmanaged arg */
  85.   if (moreargs() && ((*xlargv == k_managed) || (*xlargv == k_unmanaged)))
  86.     managed_p = (nextarg() == k_managed);
  87.   else
  88.     managed_p = FALSE;        /* by default don't call XtManageChild() */
  89.  
  90.   /* get optional <name> arg */
  91.   if (moreargs() && (stringp(*xlargv)))
  92.     name = (char*) getstring(nextarg());
  93.   else
  94.     name = "";            /* default name */
  95.  
  96.   /* get required <parent> widget-object arg */
  97.   parent_widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&o_parent);
  98.  
  99.   /*
  100.    * Store the widget object <self> in the XmNuserData resource on the
  101.    * widget. This will allow us to retrieve the widget object from Xtoolkit
  102.    * functions returning widget ID's without having to keep around a table
  103.    * of widgetID-->widget-objects.
  104.    */
  105.    ARGLIST_RESET(); ARGLIST_ADD(XmNuserData, (XtArgVal) self); 
  106.  
  107.   if (moreargs()) {        /* if there are more arguments, */
  108.     Cardinal xt_numargs;    /* then we have some extra widget resources to set */
  109.     ArgList xt_arglist = Wres_Get_LispArglist(self, parent_widget_id, ARGLIST(), &xt_numargs);
  110.     widget_id = XmCreateCommand(parent_widget_id, name, xt_arglist, xt_numargs);
  111.     Wres_Free_C_Arglist_Data();
  112.   }
  113.   else 
  114.     widget_id = XmCreateCommand(parent_widget_id, name, ARGLIST());
  115.   
  116.   Wcls_Initialize_WIDGETOBJ(self, widget_id);
  117.  
  118.   if (managed_p)
  119.     XtManageChild(widget_id);
  120.  
  121. #ifdef DEBUG_WINTERP_1
  122.   Wcls_Print_WidgetObj_Info(self);
  123. #endif
  124.   return (self);
  125. }
  126.  
  127.  
  128. /******************************************************************************
  129.  * typedef struct
  130.  * {
  131.  *     int reason;
  132.  *     XEvent    *event;
  133.  *     XmString    value;
  134.  *     int    length;
  135.  * } XmCommandCallbackStruct;
  136.  ******************************************************************************/
  137. static void Lexical_Bindings_For_XmCommandCallbackStruct(bindings_list, lexical_env, cd, o_widget)
  138.      LVAL bindings_list;    /* a list of symbols to which values from XmCommandCallbackStruct are bound */
  139.      LVAL lexical_env;        
  140.      XmCommandCallbackStruct* cd;
  141.      LVAL o_widget;        /* XLTYPE_WIDGETOBJ */
  142. {
  143.   extern LVAL s_CALLBACK_WIDGET, s_CALLBACK_REASON, s_CALLBACK_XEVENT, s_CALLBACK_VALUE, s_CALLBACK_LENGTH; /* w_callbacks.c */
  144.   extern LVAL Wcb_Get_Callback_Reason_Symbol();    /* w_callbacks.c */
  145.   register LVAL s_bindname;
  146.  
  147.   for ( ; consp(bindings_list); bindings_list = cdr(bindings_list)) {
  148.  
  149.     s_bindname = car(bindings_list);
  150.  
  151.     if (s_bindname == s_CALLBACK_WIDGET) {
  152.       xlpbind(s_bindname, o_widget, lexical_env);
  153.     }
  154.     else if (s_bindname == s_CALLBACK_REASON) {
  155.       xlpbind(s_bindname, Wcb_Get_Callback_Reason_Symbol(cd->reason), lexical_env);
  156.     }
  157.     else if (s_bindname == s_CALLBACK_XEVENT) {
  158.       xlpbind(s_bindname, (cd->event) ? cv_xevent(cd->event) : NIL, lexical_env);
  159.     }
  160.     else if (s_bindname == s_CALLBACK_VALUE) {
  161.       xlpbind(s_bindname, (cd->value) ? cv_xmstring(XmStringCopy(cd->value)) : NIL, lexical_env);
  162.     }
  163.     else if (s_bindname == s_CALLBACK_LENGTH) {
  164.       xlpbind(s_bindname, cvfixnum((FIXTYPE) cd->length), lexical_env);
  165.     }
  166.     else {
  167.       extern char temptext[];    /* from winterp.c */
  168.       sprintf(temptext,
  169.           "Unknown binding name in XmCommandCallbackStruct callback evaluator. Valid symbols are [%s %s %s %s %s].",
  170.           (char*) getstring(getpname(s_CALLBACK_WIDGET)),
  171.           (char*) getstring(getpname(s_CALLBACK_REASON)),
  172.           (char*) getstring(getpname(s_CALLBACK_XEVENT)),
  173.           (char*) getstring(getpname(s_CALLBACK_VALUE)),
  174.           (char*) getstring(getpname(s_CALLBACK_LENGTH)));
  175.       xlerror(temptext, s_bindname);
  176.     }
  177.   }
  178. }
  179.  
  180.  
  181. /******************************************************************************
  182.  * This is called indirectly via XtAddCallback() for callbacks returning
  183.  * an XmCommandCallbackStruct as call_data.
  184.  ******************************************************************************/
  185. static void XmCommandCallbackStruct_Callbackproc(widget, client_data, call_data)
  186.      Widget    widget;
  187.      XtPointer client_data;
  188.      XtPointer call_data;
  189. {
  190.   extern void Wcb_Meta_Callbackproc(); /* w_callbacks.c */
  191.  
  192.   Wcb_Meta_Callbackproc(client_data, call_data,
  193.             Lexical_Bindings_For_XmCommandCallbackStruct,
  194.             NULL);
  195. }
  196.  
  197.  
  198. /******************************************************************************
  199.  * Same as WIDGET_CLASS's :add_callback method except that this understands
  200.  * how to get values from the XmCommandCallbackStruct.
  201.  * Specifying one or more of the following symbols in the callback bindings 
  202.  * list will bind that symbol's value in the lexical environment of the callback:
  203.  * CALLBACK_WIDGET
  204.  * CALLBACK_REASON
  205.  * CALLBACK_XEVENT
  206.  * CALLBACK_VALUE
  207.  * CALLBACK_LENGTH
  208.  ******************************************************************************/
  209. LVAL Xm_Command_Widget_Class_Method_ADD_CALLBACK()
  210. {
  211.   extern LVAL Wcb_Meta_Method_Add_Callback(); /* w_callbacks.c */
  212.  
  213.   return (Wcb_Meta_Method_Add_Callback(XmCommandCallbackStruct_Callbackproc, FALSE));
  214. }
  215.  
  216.  
  217. /******************************************************************************
  218.  * Same as WIDGET_CLASS's :set_callback method except that this understands
  219.  * how to get values from the XmCommandCallbackStruct.
  220.  * Specifying one or more of the following symbols in the callback bindings 
  221.  * list will bind that symbol's value in the lexical environment of the callback:
  222.  * CALLBACK_WIDGET
  223.  * CALLBACK_REASON
  224.  * CALLBACK_XEVENT
  225.  * CALLBACK_VALUE
  226.  * CALLBACK_LENGTH
  227.  ******************************************************************************/
  228. LVAL Xm_Command_Widget_Class_Method_SET_CALLBACK()
  229. {
  230.   extern LVAL Wcb_Meta_Method_Add_Callback(); /* w_callbacks.c */
  231.  
  232.   return (Wcb_Meta_Method_Add_Callback(XmCommandCallbackStruct_Callbackproc, TRUE));
  233. }
  234.  
  235.  
  236. /******************************************************************************
  237.  * (send <commandwidget> :get_child <symbol>)
  238.  * This method returns a WIDGETOBJ corresonding to <symbol>
  239.  * <symbol> can be :DIALOG_COMMAND_TEXT,
  240.  *                 :DIALOG_HISTORY_LIST, or
  241.  *                 :DIALOG_PROMPT_LABEL
  242.  *
  243.  * Widget XmCommandGetChild (widget, child)
  244.  * Widget   widget;
  245.  * unsigned char   child;
  246.  ******************************************************************************/
  247. LVAL Xm_Command_Widget_Class_Method_GET_CHILD()
  248. {
  249.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ();
  250.   extern LVAL s_XmDIALOG_COMMAND_TEXT, s_XmDIALOG_HISTORY_LIST, s_XmDIALOG_PROMPT_LABEL;
  251.   LVAL self, lval_child;
  252.   Widget widget_id;
  253.   unsigned char child;
  254.  
  255.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  256.   lval_child = xlgasymbol();
  257.   xllastarg();
  258.   
  259.   if (lval_child == s_XmDIALOG_COMMAND_TEXT)
  260.     child = XmDIALOG_COMMAND_TEXT;
  261.   else if (lval_child == s_XmDIALOG_HISTORY_LIST)
  262.     child = XmDIALOG_HISTORY_LIST;
  263.   else if (lval_child == s_XmDIALOG_PROMPT_LABEL)
  264.     child = XmDIALOG_PROMPT_LABEL;
  265.   else 
  266.     xlerror("COMMAND_WIDGET_CLASS method :GET_CHILD -- unknown child type.", lval_child);
  267.  
  268.   return (Wcls_WidgetID_To_WIDGETOBJ(XmCommandGetChild(widget_id, child)));
  269. }
  270.  
  271.  
  272. /******************************************************************************
  273.  * (send <commandwidget> :set_value <value>)
  274.  * This sets the text in the widget's command area to the string or XmString
  275.  * <value>. If a normal string is given, it will be converted to an XmString
  276.  * and returned as the  method's result.
  277.  *
  278.  * void XmCommandSetValue (widget, value)
  279.  * Widget   widget;
  280.  * XmString value;
  281.  ******************************************************************************/
  282. LVAL Xm_Command_Widget_Class_Method_SET_VALUE()
  283. {
  284.   LVAL self, lval_value;
  285.   Widget widget_id;
  286.   XmString value;
  287.   extern XmString Get_String_or_XmString_Arg_Returning_XmString(); /* w_XmString.c */
  288.  
  289.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  290.   value = Get_String_or_XmString_Arg_Returning_XmString(&lval_value);
  291.   xllastarg();
  292.   
  293.   /* the lame part about all this is that the XmString value that we may
  294.      have converted above will just be cvted back to a string below. */
  295.   XmCommandSetValue(widget_id, value);
  296.   
  297.   return (lval_value);
  298. }
  299.  
  300.  
  301. /******************************************************************************
  302.  * (send <commandwidget> :append_value <value>)
  303.  * This appends the string or XmString <value> to the string in the command
  304.  * area widget. If a normal string is given, it will be converted to an
  305.  * XmString and returned as the method's result.
  306.  * 
  307.  * void XmCommandAppendValue (widget, value)
  308.  * Widget widget;
  309.  * XmString value;
  310.  ******************************************************************************/
  311. LVAL Xm_Command_Widget_Class_Method_APPEND_VALUE()
  312. {
  313.   LVAL self, lval_value;
  314.   Widget widget_id;
  315.   XmString value;
  316.   extern XmString Get_String_or_XmString_Arg_Returning_XmString(); /* w_XmString.c */
  317.  
  318.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  319.   value = Get_String_or_XmString_Arg_Returning_XmString(&lval_value);
  320.   xllastarg();
  321.   
  322.   /* the lame part about all this is that the XmString value that we may
  323.      have converted above will just be cvted back to a string below */
  324.   XmCommandAppendValue(widget_id, value);
  325.   
  326.   return (lval_value);
  327. }
  328.  
  329.  
  330. /******************************************************************************
  331.  * (send <commandwidget> :error <error>)
  332.  * This temporarily displays the string or XmString <error> in the history
  333.  * area of the command widget, the display is cleared upon entry of the
  334.  * next command. If a normal string is given, it will be converted to an
  335.  * XmString and returned as the method's result.
  336.  *
  337.  * void XmCommandError (widget, error)
  338.  * Widget widget;
  339.  * XmString error;
  340.  ******************************************************************************/
  341. LVAL Xm_Command_Widget_Class_Method_ERROR()
  342. {
  343.   LVAL self, lval_value;
  344.   Widget widget_id;
  345.   XmString value;
  346.   extern XmString Get_String_or_XmString_Arg_Returning_XmString(); /* w_XmString.c */
  347.  
  348.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  349.   value = Get_String_or_XmString_Arg_Returning_XmString(&lval_value);
  350.   xllastarg();
  351.   
  352.   /* the lame part about all this is that the XmString value that we may
  353.      have converted above will just be cvted back to a string below */
  354.   XmCommandError(widget_id, value);
  355.   
  356.   return (lval_value);
  357. }
  358.  
  359.  
  360. /******************************************************************************
  361.  * (send <commandwidget> :GET_HISTORY_ITEMS)
  362.  *     ==> returns an array of XmStrings.
  363.  *
  364.  * This retrieves the XmCommand widget resources XmNhistoryItems and
  365.  * XmNhistoryItemCount from <commandwidget> and returns an array of XmStrings
  366.  * representing the history items.
  367.  *******************************************************************************/
  368. LVAL Xm_Command_Widget_Class_Method_GET_HISTORY_ITEMS()
  369. {
  370.   LVAL self;
  371.   Widget widget_id;
  372.   XmStringTable xmstrtab;
  373.   int        xmstrtab_size;
  374.  
  375.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  376.   xllastarg();
  377.  
  378.   ARGLIST_RESET();
  379.   ARGLIST_ADD(XmNhistoryItems, &xmstrtab);
  380.   ARGLIST_ADD(XmNhistoryItemCount, &xmstrtab_size);
  381.   XtGetValues(widget_id, ARGLIST());
  382.  
  383.   return (Wxms_XmStringTable_To_Lisp_Vector(xmstrtab, xmstrtab_size));
  384. }
  385.  
  386.  
  387. /******************************************************************************
  388.  *
  389.  ******************************************************************************/
  390. Wc_Command_Init()
  391. {
  392.   LVAL o_XM_COMMAND_WIDGET_CLASS;
  393.   extern LVAL Wcls_Create_Subclass_Of_WIDGET_CLASS(); /* w_classes.c */
  394.   extern      xladdmsg();    /* from xlobj.c */
  395.  
  396.   o_XM_COMMAND_WIDGET_CLASS =
  397.     Wcls_Create_Subclass_Of_WIDGET_CLASS("XM_COMMAND_WIDGET_CLASS",
  398.                      xmCommandWidgetClass);
  399.  
  400.   /* a special :isnew method on this class allows for the creation of this
  401.    * widget with Command.c:XmCreateCommand(), rather than using default
  402.    * :ISNEW (which does XtCreateWidget()). The only special thing done by
  403.    * XmCreateCommand() is that it prepends the following arg to the arglist:
  404.    * XmNdialogType == XmDIALOG_COMMAND.
  405.    */
  406.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":ISNEW", 
  407.        FTAB_Xm_Command_Widget_Class_Method_ISNEW);
  408.  
  409.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":ADD_CALLBACK",
  410.            FTAB_Xm_Command_Widget_Class_Method_ADD_CALLBACK);
  411.  
  412.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":SET_CALLBACK",
  413.            FTAB_Xm_Command_Widget_Class_Method_SET_CALLBACK);
  414.  
  415.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":GET_CHILD",
  416.            FTAB_Xm_Command_Widget_Class_Method_GET_CHILD);
  417.  
  418.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":ERROR",
  419.        FTAB_Xm_Command_Widget_Class_Method_ERROR);
  420.  
  421.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":SET_VALUE",
  422.        FTAB_Xm_Command_Widget_Class_Method_SET_VALUE);
  423.  
  424.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":APPEND_VALUE",
  425.        FTAB_Xm_Command_Widget_Class_Method_APPEND_VALUE);
  426.  
  427.   xladdmsg(o_XM_COMMAND_WIDGET_CLASS, ":GET_HISTORY_ITEMS",
  428.        FTAB_Xm_Command_Widget_Class_Method_GET_HISTORY_ITEMS);
  429. }
  430.